#include "filetransferdialog.h"
#include <QFileDialog>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QDateTime>
#include <QDebug>

FileTransferDialog::FileTransferDialog(QWidget *parent) : QDialog(parent),
    ui(new Ui::FileTransferDialog),
    socket(new QTcpSocket(this)),
    file(nullptr),
    totalBytes(0),
    bytesTransferred(0),
    bytesToWrite(0),
    payloadSize(64 * 1024),
    isPaused(false),
    isUploading(false)
{
    ui->setupUi(this);

    // 连接信号和槽
    connect(socket, &QTcpSocket::readyRead, this, &FileTransferDialog::onSocketReadyRead);
    connect(socket, &QTcpSocket::bytesWritten, this, &FileTransferDialog::onSocketBytesWritten);

}

FileTransferDialog::~FileTransferDialog()
{
    if (file) {
        file->close();
        delete file;
    }
    delete ui;
}

void FileTransferDialog::onUploadButtonClicked()
{

}

void FileTransferDialog::on_add_clicked()//选择文件
{
    QString filePath = QFileDialog::getOpenFileName(this, "选择要上传的文件");
    if (!filePath.isEmpty()) {
        ui->filePathLineEdit->setText(filePath);
    }
}

void FileTransferDialog::on_start_clicked()//开始传输
{
    QString filePath = ui->filePathLineEdit->text();
    if (filePath.isEmpty()) {
        ui->statusLabel->setText("请先选择文件");
        return;
    }

    file = new QFile(filePath);
    if (!file->open(QIODevice::ReadOnly)) {
        ui->statusLabel->setText("无法打开文件");
        return;
    }

    totalBytes = file->size();
    bytesTransferred = 0;
    bytesToWrite = totalBytes;

    isUploading = true;

    socket->connectToHost("127.0.0.1", 12345); // 连接到服务器
    if (socket->waitForConnected()) {
        // 发送文件头信息
        QByteArray header;
        QDataStream headerStream(&header, QIODevice::WriteOnly);
        headerStream.setVersion(QDataStream::Qt_5_15);
        headerStream << qint64(0) << qint64(0) << file->fileName();
        totalBytes += header.size();
        bytesToWrite += header.size();
        headerStream.device()->seek(0);
        headerStream << totalBytes << qint64(header.size() - sizeof(qint64) * 2);
        socket->write(header);
        ui->statusLabel->setText("开始上传");
    } else {
        ui->statusLabel->setText("无法连接到服务器");
        file->close();
        delete file;
        file = nullptr;
    }
}

void FileTransferDialog::on_clear_clicked()//清除/暂停
{
    if (isUploading) {
        isPaused = true;

        ui->statusLabel->setText("传输暂停");
    } else {
        ui->filePathLineEdit->clear();
        ui->statusLabel->clear();
        ui->progressBar->reset();
    }
}

void FileTransferDialog::onDownloadButtonClicked()
{
    QString savePath = QFileDialog::getSaveFileName(this, "选择保存路径");
    if (savePath.isEmpty()) return;

    file = new QFile(savePath);
    if (!file->open(QIODevice::WriteOnly)) {
        ui->statusLabel->setText("无法打开文件");
        return;
    }

    totalBytes = 0;
    bytesTransferred = 0;
    bytesToWrite = 0;

    isUploading = false;

    socket->connectToHost("127.0.0.1", 11000); // 连接到服务器
    if (socket->waitForConnected()) {
        // 发送下载请求
        QByteArray request;
        QDataStream requestStream(&request, QIODevice::WriteOnly);
        requestStream.setVersion(QDataStream::Qt_5_15);
        requestStream << qint64(0) << qint64(1); // 1 表示下载请求
        requestStream.device()->seek(0);
        requestStream << qint64(request.size());
        socket->write(request);
        ui->statusLabel->setText("开始下载");
    } else {
        ui->statusLabel->setText("无法连接到服务器");
        file->close();
        delete file;
        file = nullptr;
    }
}

void FileTransferDialog::onPauseButtonClicked()
{
    isPaused = true;

    ui->statusLabel->setText("传输暂停");
}

void FileTransferDialog::onResumeButtonClicked()
{
    isPaused = false;

    ui->statusLabel->setText("继续传输");
    if (isUploading) {
        onSocketBytesWritten(0);
    }
}

void FileTransferDialog::onCancelButtonClicked()
{
    if (socket->state() == QTcpSocket::ConnectedState) {
        socket->disconnectFromHost();
        if (socket->waitForDisconnected()) {
            ui->statusLabel->setText("传输已取消");
        }
    }
    if (file) {
        file->close();
        delete file;
        file = nullptr;
    }

}

void FileTransferDialog::onSocketReadyRead()
{
    if (isUploading) return;

    QDataStream in(socket);
    in.setVersion(QDataStream::Qt_5_15);

    if (bytesTransferred == 0) {
        if (socket->bytesAvailable() < sizeof(qint64) * 2) return;
        in >> totalBytes >> bytesToWrite;
        ui->progressBar->setMaximum(totalBytes);
    }

    while (socket->bytesAvailable() > 0 && bytesTransferred < totalBytes) {
        QByteArray buffer = socket->read(qMin(socket->bytesAvailable(), totalBytes - bytesTransferred));
        file->write(buffer);
        bytesTransferred += buffer.size();
        updateProgress(bytesTransferred);
    }

    if (bytesTransferred == totalBytes) {
        file->close();
        ui->statusLabel->setText("下载完成");

    }
}

void FileTransferDialog::onSocketBytesWritten(qint64 bytes)
{
    if (isPaused) return;

    bytesTransferred += bytes;
    bytesToWrite -= bytes;
    updateProgress(bytesTransferred);

    if (bytesToWrite > 0) {
        QByteArray buffer = file->read(qMin(bytesToWrite, payloadSize));
        socket->write(buffer);
    } else {
        file->close();
        ui->statusLabel->setText("上传完成");

    }
}

void FileTransferDialog::updateProgress(qint64 bytesTransferred)
{
    ui->progressBar->setValue(bytesTransferred);

    // 计算传输速度和剩余时间
    static QDateTime startTime = QDateTime::currentDateTime();
    qint64 elapsedTime = startTime.msecsTo(QDateTime::currentDateTime());
    if (elapsedTime > 0) {
        double speed = bytesTransferred / (elapsedTime / 1000.0);
        qint64 remainingBytes = totalBytes - bytesTransferred;
        qint64 remainingTime = remainingBytes / speed;

        QString statusText = QString("已传输: %1/%2 bytes, 速度: %3 KB/s, 剩余时间: %4 s")
                                 .arg(bytesTransferred).arg(totalBytes)
                                 .arg(speed / 1024, 0, 'f', 2)
                                 .arg(remainingTime);
        ui->statusLabel->setText(statusText);
    }
}

void FileTransferDialog::on_onUpload_clicked()
{
    QString filePath = QFileDialog::getOpenFileName(this, "选择要上传的文件");
    if (filePath.isEmpty()) return;

    file = new QFile(filePath);
    if (!file->open(QIODevice::ReadOnly)) {
        ui->statusLabel->setText("无法打开文件");
        return;
    }

    totalBytes = file->size();
    bytesTransferred = 0;
    bytesToWrite = totalBytes;

    isUploading = true;

    socket->connectToHost("127.0.0.1", 12345); // 连接到服务器
    if (socket->waitForConnected()) {
        // 发送文件头信息
        QByteArray header;
        QDataStream headerStream(&header, QIODevice::WriteOnly);
        headerStream.setVersion(QDataStream::Qt_5_15);
        headerStream << qint64(0) << qint64(0) << file->fileName();
        totalBytes += header.size();
        bytesToWrite += header.size();
        headerStream.device()->seek(0);
        headerStream << totalBytes << qint64(header.size() - sizeof(qint64) * 2);
        socket->write(header);
        ui->statusLabel->setText("开始上传");
    } else {
        ui->statusLabel->setText("无法连接到服务器");
        file->close();
        delete file;
        file = nullptr;
    }
}

